/*
 * Copyright (c) 2015 Intel Corporation
 *
 * SPDX-License-Identifier: Apache-2.0
 */
#include <zephyr/kernel.h>
#include <zephyr/shell/shell.h>
#include <version.h>
#include <zephyr/logging/log.h>
#include <stdlib.h>
#include <stdio.h>
#include <zephyr/drivers/uart.h>
#include <zephyr/usb/usb_device.h>
#include <ctype.h>
#include <zephyr/arch/cpu.h>
#include <zephyr/sys/util.h>
#include <zephyr/linker/linker-defs.h>
#include <zephyr/device.h>
#include <zephyr/shell/shell_uart.h>
#include <zephyr/drivers/flash.h>
#include <zephyr/irq.h>
#include <zephyr/drivers/watchdog.h>
#include <zephyr/devicetree.h>
#include <../../dolphin_common/include/motor.h>
#include <../../dolphin_common/include/Ymodem.h>
#include <../../dolphin_common/include/relay.h>
#include <../../dolphin_common/include/common.h>
#include <../../dolphin_common/include/servo.h>
#include <../../dolphin_common/include/stepmotor.h>
#include <../../dolphin_common/include/jetson_nano.h>
#include <zephyr/device.h>
#include <zephyr/drivers/pwm.h>
#include <zephyr/sys/printk.h>
/*********************************************************************
 * 需要的标志定义
 *********************************************************************/
#define APP_OFFSET_ADDR  0x00020000  //定义app的基地址，相应得要在app工程文件menuconfig中修改

#define BOOT_SIZE_SIGN_OFFSET_ADDR  0x000EFFE0 - APP_OFFSET_ADDR //flash的一个区域划为boot程序大小标记
#define APP_SIZE_SIGN_OFFSET_ADDR  0x000EFFF0 - APP_OFFSET_ADDR  //flash的一个区域划为app程序大小标记

#define RS485_RX_STACK_SIZE 512
#define RS485_RX_PRIORITY  4

#define NANO_RX_STACK_SIZE 512
#define NANO_RX_PRIORITY  4

#define NANO_TX_STACK_SIZE 512
#define NANO_TX_PRIORITY  4

#define MOTOR_GET_STACK_SIZE 512
#define MOTOR_GET_PRIORITY  8
/*********************************************************************
 * 函数声明
 *********************************************************************/
LOG_MODULE_REGISTER(main);
void shell_uninit_cb(const struct shell *shell, int res);
void shell_reinit_trigger(void);
void shell_uninit_download_cb(const struct shell *shell, int res);
void rs485_rx_dispense(void *p1, void *p2, void *p3);
void motor_get_handler(void *p1, void *p2, void *p3);
/*********************************************************************
 * 全局变量及外部变量声明
 *********************************************************************/
uint32_t FLASH_BASE_ADDR = 0x08020000;
k_thread_stack_t  rs485_rx_stack_area[RS485_RX_STACK_SIZE]; //485收帧分发任务线程
struct k_thread rs485_rx_thread;
k_tid_t rs485_rx_tid;

k_thread_stack_t  nano_rx_stack_area[NANO_RX_STACK_SIZE]; //485收帧分发任务线程
struct k_thread nano_rx_thread;
k_tid_t nano_rx_tid;

k_thread_stack_t  nano_tx_stack_area[NANO_TX_STACK_SIZE]; //485收帧分发任务线程
struct k_thread nano_tx_thread;
k_tid_t nano_tx_tid;

k_thread_stack_t  motor_get_stack_area[MOTOR_GET_STACK_SIZE]; //485收帧分发任务线程
struct k_thread motor_get_thread;
k_tid_t motor_get_tid;
extern Motor_Para Motor_Para_g;

// #define LEAK_RX_STACK_SIZE 512
// #define LEAK_RX_PRIORITY  4
// k_thread_stack_t  leak_rx_stack_area[LEAK_RX_STACK_SIZE]; //485收帧分发任务线程
// struct k_thread leak_rx_thread;
// k_tid_t leak_rx_tid;

#define IMU_RX_STACK_SIZE 4096
#define IMU_RX_PRIORITY  4
k_thread_stack_t  imu_rx_stack_area[IMU_RX_STACK_SIZE]; //485收帧分发任务线程
struct k_thread imu_rx_thread;
k_tid_t imu_rx_tid;

#define DIR_PWM
#define DEFAULT_IIC_NODE DT_ALIAS(myi2c)

const struct device *uart_motor = DEVICE_DT_GET(DT_ALIAS(uartmotor));
const struct device *uart_imu0 = DEVICE_DT_GET(DT_ALIAS(uartimu0));

const struct gpio_dt_spec *relay_motor = &(const struct gpio_dt_spec)GPIO_DT_SPEC_GET(DT_ALIAS(relaymotor), gpios);
const struct gpio_dt_spec *relay_stepmotor =  &(const struct gpio_dt_spec)GPIO_DT_SPEC_GET(DT_ALIAS(relaystepmotor), gpios);
const struct gpio_dt_spec *relay_servo = &(const struct gpio_dt_spec)GPIO_DT_SPEC_GET(DT_ALIAS(relayservo), gpios);
const struct gpio_dt_spec *leak_detect = &(const struct gpio_dt_spec)GPIO_DT_SPEC_GET(DT_ALIAS(leakdetect), gpios);

const struct gpio_dt_spec *stepmotor_dir = &(const struct gpio_dt_spec)GPIO_DT_SPEC_GET(DT_ALIAS(stepmotordir), gpios);
const struct gpio_dt_spec *stepmotor_limit = &(const struct gpio_dt_spec)GPIO_DT_SPEC_GET(DT_ALIAS(stepmotorlimit), gpios);
const struct pwm_dt_spec *stepmotor_pwm = &(const struct pwm_dt_spec)PWM_DT_SPEC_GET(DT_ALIAS(stepmotor));
//const struct pwm_dt_spec stepmotor_pwm = PWM_DT_SPEC_GET(DT_ALIAS(stepmotor));
const struct device *const i2c_dev = DEVICE_DT_GET(DEFAULT_IIC_NODE);


/*******************************************************************************
  * @函数名称	app_prep_init
  * @函数说明   APP前期初始化
  * @输入参数   无:
  * @输出参数   无
  * @返回参数   无
*******************************************************************************/
void app_prep_init(void)
{
	static const struct device *flash_device =
		DEVICE_DT_GET_OR_NULL(DT_CHOSEN(zephyr_flash_controller));
	uint8_t buf[10];
	int32_t app_size;

	flash_read(flash_device,APP_SIZE_SIGN_OFFSET_ADDR ,buf ,10);
	app_size  = str2int(buf) ;
	k_sleep(K_MSEC(50));
	LOG_INF("app_offset_addr is 0x%x, app_size is %d\r\n",APP_OFFSET_ADDR,app_size);
}

/*******************************************************************************
  * @函数名称	motor_get_timer_handler
  * @函数说明   定时上报主控
  * @输入参数   定时器接口
  * @输出参数   无
  * @返回参数   无
*******************************************************************************/
void motor_get_handler(void *p1, void *p2, void *p3)
{
	while(1){
		Motor_Ctr_API(uart_motor,Read_Status_one());
		k_sleep(K_MSEC(10));
		Motor_Ctr_API(uart_motor,Read_Status_two());
		k_sleep(K_MSEC(10));
	}
}

void main(void)
{
	LOG_INF("Enter App ...");
	//看门狗初始化
	watchdog_init();

	//app前期初始化
	app_prep_init();
	
	imu_init();	
	//开关继电器初始化
    Relay_open(ALL);
	
	// //定时获取电机信息
    motor_get_tid = k_thread_create(&motor_get_thread,motor_get_stack_area, MOTOR_GET_STACK_SIZE,
                                 motor_get_handler, NULL, NULL, NULL,
                                  IMU_RX_PRIORITY, 0, K_NO_WAIT);
	
	//创建485收帧分发任务线程
    rs485_rx_tid = k_thread_create(&rs485_rx_thread,rs485_rx_stack_area, RS485_RX_STACK_SIZE,
                                 rs485_rx_dispense, NULL, NULL, NULL,
                                  RS485_RX_PRIORITY, 0, K_NO_WAIT);
	//创建主控收帧分发任务线程
    nano_rx_tid = k_thread_create(&nano_rx_thread,nano_rx_stack_area,NANO_RX_STACK_SIZE,
                                 nano_rx_dispense, NULL, NULL, NULL,
                                  NANO_RX_PRIORITY, 0, K_NO_WAIT);

	//创建设备向主控发送状态信息线程
    nano_tx_tid = k_thread_create(&nano_tx_thread,nano_tx_stack_area,NANO_TX_STACK_SIZE,
                                 nano_tx_dispense, NULL, NULL, NULL,
                                  NANO_TX_PRIORITY, 0, K_NO_WAIT);

	//创建IMU传感器收帧任务线程
    imu_rx_tid = k_thread_create(&imu_rx_thread,imu_rx_stack_area, IMU_RX_STACK_SIZE,
                                 imu_rx_dispense, NULL, NULL, NULL,
                                  IMU_RX_PRIORITY, 0, K_NO_WAIT);

	//执行机构初始化
	motor_init(uart_motor);
	Servo_init();
	Stepmotor_init(); //死等
	//传感器初始化
	
}


